/*
 * LAB10.C
 *
 * Author: Evan Zimmerman <zimmermane@msoe.edu>
 *         Kevin Duer <duerk@msoe.edu>
 * Date: 11/8/12
 * Course: CE4920-001
 * Instructor: Barnicki
 */ 

#include<avr/io.h>//i/o register definitions
#include<avr/interrupt.h>//interrupt definitions
#include <avr/eeprom.h>//for eeprom

uint8_t wave[100];//100 samples of the wave
static volatile uint8_t numSamples=0;//number of samples that have been taken
static volatile uint8_t waveIndex=0;//index into the wave samples
static volatile uint8_t numRecreations=0;//number of wave recreations
static volatile uint8_t numSamplesPlayed=0;//number of samples played back

void init(){
	DDRA=0x00;//ADC direction set to input
	DDRD=0x00;//DDRD set to input
	DDRC=0xFF;//DDRC set to output
	PORTD=0x0C;//turn on INT0 and INT1 pull ups

	for(int i=0;i<100;i++){
		wave[i]=0x00;//fill 100 bytes eeprom with 0
	}

	MCUCR|=(1<<ISC11)|(1<<ISC01);//enable INT0 and INT1 falling edge interrupts
	GICR|=(1<<INT1)|(1<<INT0);//enable INT0 and INT1 interrupts
	sei();//enable global interrupts

	while(1){}
}

ISR(INT0_vect){
		numRecreations=0;//reset number of wave recreations
		numSamplesPlayed=0;//reset number of samples
		TIMSK|=(1<<OCIE0);//turn on timer/counter 0 output compare interrupt enable
		OCR0=50; //)(8000000/8)*100=100us, the sampling period of 4x oversampling
		TCCR0|=((1<<WGM01)|(1<<CS01));//set timer/counter 1 for CTC mode and 
                                 	//prescaler of 8,start timer/counter 0
}

ISR(INT1_vect){
	numSamples=0;//reset number of samples to zero
	waveIndex=0;//reset index into wave samples
	numRecreations=0;//reset number of wave recreations
	numSamplesPlayed=0;//reset number of samples played
	ADMUX|=(1<<REFS0)|(1<<ADLAR)|(1<<MUX2)|(1<<MUX0);//set ADC with VCC as reference and left adjusted,sample from ADC5
	ADCSRA|=(1<<ADEN)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS0);//Enable ADC,left adjust, and set prescalar at 125kHz 
	                                                 //for 4x oversampling
	TIMSK|=(1<<OCIE2);//turn on timer/counter 2 output compare interrupt enable
	OCR2=50; //)(8000000/8)*100=100us, the sampling period of 4x oversampling
	TCCR2|=((1<<WGM21)|(1<<CS21));//set timer/counter 2 for CTC mode and 
                                  //prescaler of 8,start timer/counter 2
}

ISR(ADC_vect){
	wave[waveIndex]=ADCH;//save ADC result to EEPROM
	waveIndex++;//increment the wave index

	if(waveIndex==100){//after 100 samples...
		TCCR2&=~(1<<CS21);//turn off timer/counter 2,thus dusabling interrupts
	}
}

ISR(TIMER0_COMP_vect){
	uint8_t currentSample; //the current sample to play

	if(numRecreations<100){
		currentSample=wave[numSamplesPlayed];//get current sample
		PORTC=currentSample*2;//output current sample,scale for DAC
		numSamplesPlayed++;//increment number of samples played

		if(numSamplesPlayed==100){//a whole wave had been recreated
			numRecreations++;//increment number of recreations
			numSamplesPlayed=0;//reset samples played to zero if there have been 100
		}                      //this gives 100 wave recreations
	}
	else{
		TCCR0&=~(1<<CS01);//disable timer/counter 0 after 100 recreations
	}

}

ISR(TIMER2_COMP_vect){
	ADCSRA|=(1<<ADSC);//start ADC conversion
}

int main(){
	init();
	return 1;
}